Odin Structs
Table of Contents
1. Struct Definition
The basic grammar for structs is similar to C.
Rectangle :: struct {
x: f32,
y: f32,
width: f32,
height: f32,
}
Then we can use := to initialize instances.
rect := Rectangle {
width = 20,
height = 10,
}
Unmentioned fields will be automatically initialized to zero value.
2. Structs within Structs
Basically, since structs are types, so we can define fields of other structs within a struct.
Person_Stats :: struct {
health: int,
age: int,
}
Person :: struct {
stats: Person_Stats,
name: string,
}
We can then initialize Person instances in a nested way, as well as accessing Person fields nestedly.
p := Person {
stats = {
health = 7,
},
name = "Bob",
}
p.name = "Bobinski"
p.stats.age = 36
2.1. using on Struct Fields
It’s sometime too redundant to type p.stats.age. By using keyword, we can make age field directly available on p.
Person :: struct {
using stats: Person_Stats,
name: string,
}
Not only we can access it directly, we can also initialize it directly.
p := Person {
health = 7,
name = "Bob",
}
2.2. using Acts like Inheritance
The using keyword can play the role of inheritance to some extend. In this example, although p is of type Person, but since Person is using type Entity, calling printposition with p that requires an Entity argument still compiles.
Entity :: struct {
id: int,
position: [2]int,
}
Person :: struct {
using entity: Entity,
health: int,
}
print_position :: proc(e: Entity) {
fmt.println(e.position)
}
main :: proc() {
p := Person {
id = 1,
position = {6, 7},
health = 20,
}
print_position(p)
}
3. Using Structs as Interfaces
Although we cannot define methods on structs, we can do something similar to storing function pointers in C to make a struct an interface.
Interface :: struct {
required_name: int,
is_valid: proc(Interface, string) -> bool,
}
my_proc :: proc(i: Interface, name: string) -> bool {
return i.required_name == name
}
my_interface := Interface {
required_name = "Sf",
is_valid = my_proc,
}